#include "tlrstructmodel.h"
#include <QDebug>

TLRStructModel::TLRStructModel()
{

}

/*
 * 从JSON字符串中加载
 * njsonstr : json字符串
 */
void TLRStructModel::loadFromJson(const QByteArray &njsondata)
{
    m_lrstructModel.clear();
    m_cmdButtonModel.clear();
    m_calibModel.clear();
    QJsonDocument njsondoc = QJsonDocument::fromJson(njsondata);
    if(!njsondoc.isNull()) {
        if(njsondoc.isObject()) {
            QJsonObject njsonbj_root = njsondoc.object();
            //通讯方式
            QString ncommtypestr = njsonbj_root.value("CommType").toString("net");
            if(ncommtypestr == "net") {
                m_commType = TCommType::ctNet;
            }
            else if(ncommtypestr == "serial") {
                m_commType = TCommType::ctSerial;
            }
            else if(ncommtypestr == "net_to_serial") {
                m_commType = TCommType::ctNetToSerial;
            }
            //设备识别字
            m_equidStr = njsonbj_root.value("EquIdStr").toString("-Null-");
            //串口波特率
            m_uartBaud = njsonbj_root.value("UartBaud").toInt(9600);
            //串口地址
            m_uartAddr = njsonbj_root.value("UartAddr").toInt(0);
            //UDP端口
            m_udpPort = njsonbj_root.value("UDPPort").toInt(2305);
            //结构体
            QJsonValue njsonval_structs = njsonbj_root.value("Structs");
            if(njsonval_structs.isArray()) {
                QJsonArray njsonarr_structs = njsonval_structs.toArray();
                //遍历结构
                for(int iroot=0;iroot<njsonarr_structs.size();iroot++) {
                    int ntotaloffset = 0;
                    QJsonObject njsonobj_struct = njsonarr_structs.at(iroot).toObject();
                    TLRStruct nlrstruct;
                    //结构体是否显示
                    nlrstruct.visible = njsonobj_struct.value("Visible").toBool(true);
                    //结构体名称
                    nlrstruct.name = njsonobj_struct.value("Name").toString("-Null-");
                    //起始地址
                    nlrstruct.paraStaAdd = njsonobj_struct.value("ParaStaAdd").toInt(5000);
                    qDebug() << "para sta add" << nlrstruct.paraStaAdd;
                    //解析成员
                    QJsonArray njsonarr_structmember = njsonobj_struct.value("MemberPool").toArray();
                    for(int istructmember=0;istructmember<njsonarr_structmember.size();istructmember++) {
                        QJsonObject njsonobj_structmember = njsonarr_structmember.at(istructmember).toObject();
                        TLRStructMember nlrstructmember;
                        //结构体成员名称
                        nlrstructmember.name = njsonobj_structmember.value("Name").toString("-Null-");
                        //结构体成员注释
                        nlrstructmember.desc = njsonobj_structmember.value("Desc").toString("-Null-");
                        //结构体成员类型
                        nlrstructmember.type = njsonobj_structmember.value("Type").toString("char");
                        //结构体成员数量
                        nlrstructmember.count = njsonobj_structmember.value("Count").toInt(1);
                        //结构体成员提示
                        nlrstructmember.hint = njsonobj_structmember.value("Hint").toString("");
                        //结构体偏移
                        nlrstructmember.offset = ntotaloffset;
                        //基本数据类型
                        if(nlrstructmember.isPlainDataType()) {
                            nlrstructmember.calcUnitSize();
                        }
                        //自定义数据类型
                        else {
                            nlrstructmember.calcUnitSize(getStruct(nlrstructmember.type).getSize());
                        }
                        ntotaloffset += nlrstructmember.getSize();
                        nlrstruct.appendMember(nlrstructmember);
                    }
                    //分配内存
                    nlrstruct.allocMem();
                    m_lrstructModel.append(nlrstruct);
                }
            }
            //按钮成员
            QJsonValue njsonval_buttons = njsonbj_root.value("Buttons");
            if(njsonval_buttons.isArray()) {
                QJsonArray njsonarr_buttons = njsonval_buttons.toArray();
                for(int buttonIndex=0;buttonIndex<njsonarr_buttons.size();buttonIndex++) {
                    TLRCmdButton cmdButton;
                    QJsonObject njsonobj_button = njsonarr_buttons.at(buttonIndex).toObject();
                    //按钮名称
                    cmdButton.name = njsonobj_button.value("Name").toString("-Null-");
                    //按钮IP
                    cmdButton.ip = njsonobj_button.value("IP").toString();
                    //按钮端口
                    cmdButton.port = njsonobj_button.value("Port").toInt(-1);
                    //按钮指令
                    cmdButton.cmd = njsonobj_button.value("Cmd").toString();
                    m_cmdButtonModel.append(cmdButton);
                }
            }
            //校准成员
            QJsonArray jsonarr_calib = njsonbj_root.value("Calibs").toArray();
            for(int calibIndex=0;calibIndex<jsonarr_calib.size();calibIndex++) {
                TLRCalib lrcalib;
                QJsonObject jsonobj_calib = jsonarr_calib.at(calibIndex).toObject();
                //校准名称
                lrcalib.Name = jsonobj_calib.value("Name").toString();
                //类型 0:比例 1:偏移 2:7022E
                lrcalib.type = (CalibType)jsonobj_calib.value("Type").toInt(1);
                //目标值
                lrcalib.DestVal = jsonobj_calib.value("DestVal").toInt(100);
                //校准测量值采样次数
                lrcalib.CalibCnt = jsonobj_calib.value("CalibCnt").toInt(20);
                //测量值临时参数
                QStringList paramList = jsonobj_calib.value("MeasVal").toString().split(',');
                if(paramList.size() == 2) {
                    lrcalib.meas.sta = paramList.at(0).toInt();
                    lrcalib.meas.type = paramList.at(1);
                    lrcalib.meas.len = typeToLen(lrcalib.meas.type);
                }
                //校准值临时参数
                paramList = jsonobj_calib.value("CalibVal").toString().split(',');
                if(paramList.size() == 2) {
                    if(lrcalib.type == calib7022) {
                        lrcalib.calib.sta = paramList.at(0).toInt();
                        lrcalib.calib.type = "s32";
                        lrcalib.calib.len = 4;
                    }
                    else {
                        lrcalib.calib.sta = paramList.at(0).toInt();
                        lrcalib.calib.type = paramList.at(1);
                        lrcalib.calib.len = typeToLen(lrcalib.calib.type);
                    }
                }
                //校准扩展值临时参数(仅偏移模式需要)
                paramList = jsonobj_calib.value("CalibExtVal").toString().split(',');
                if(paramList.size() == 2) {
                    lrcalib.calibExt.sta = paramList.at(0).toInt();
                    lrcalib.calibExt.type = paramList.at(1);
                    lrcalib.calibExt.len = typeToLen(lrcalib.calibExt.type);
                }
                m_calibModel.append(lrcalib);
            }
        }
    }
}

/**
 * @brief 从JSON文件中加载
 * @param filePath 文件路径
 */
void TLRStructModel::loadFromFile(const QString &filePath)
{
    if(!QFile::exists(filePath)) {
        return;
    }
    QFile fileJSON(filePath);
    fileJSON.open(QFile::ReadOnly);
    QByteArray data = fileJSON.readAll();
    fileJSON.close();
    loadFromJson(data);
}

/*
 * 获取指定名称的结构体
 * nlrstructname : 指定的结构体名称
 */
TLRStruct TLRStructModel::getStruct(const QString &nlrstructname)
{
    TLRStruct nlrstruct;
    for(int i=0;i<m_lrstructModel.size();i++) {
        TLRStruct nlrstructsrc = m_lrstructModel.at(i);
        if(nlrstructname == nlrstructsrc.name) {
            nlrstruct = nlrstructsrc;
            break;
        }
    }
    return nlrstruct;
}

/*
 * 查找指定序号的结构体
 * nindex : 序号
 */
TLRStruct TLRStructModel::getStruct(int nindex)
{
    TLRStruct nlrstruct;
    if(nindex >= 0 && nindex < m_lrstructModel.size()) {
        nlrstruct = m_lrstructModel.at(nindex);
    }
    return nlrstruct;
}

/*
 * 序号是否合理
 * nindex : 序号
 * 返回值  : true合理 false不合理
 */
bool TLRStructModel::isIndexValid(int nindex)
{
    bool nret = false;
    if((nindex >= 0) && (nindex < m_lrstructModel.size())) {
        nret = true;
    }
    return nret;
}

/*
 * 获取通讯方式
 * 返回值 : 通讯方式
 */
TCommType TLRStructModel::getCommType()
{
    return m_commType;
}

/*
 * 获取设备识别字
 */
QString TLRStructModel::getEquidStr()
{
    return m_equidStr;
}

/**
 * @brief 获取串口波特率
 * @return 串口波特率
 */
int TLRStructModel::getUartBaud()
{
    return m_uartBaud;
}

/**
 * @brief 获取串口地址
 * @return 串口地址
 */
int TLRStructModel::getUartAddr()
{
    return m_uartAddr;
}

/**
 * @brief 获取设备UDP端口
 * @return 设备UDP端口
 */
int TLRStructModel::getUDPPort()
{
    return m_udpPort;
}

/**
 * @brief 获取成员数量
 * @return
 */
int TLRStructModel::size()
{
    return m_lrstructModel.size();
}

/**
 * @brief 类型转长度
 * @param type 类型
 * @return 长度
 */
int TLRStructModel::typeToLen(const QString &type)
{
    int len = 0;
    if(type == "char") {
        len = 1;
    }
    else if(type == "u8") {
        len = 1;
    }
    else if(type == "u16") {
        len = 2;
    }
    else if(type == "s16") {
        len = 2;
    }
    else if(type == "u32") {
        len = 4;
    }
    else if(type == "s32") {
        len = 4;
    }
    else if(type == "u64") {
        len = 8;
    }
    else if(type == "s64") {
        len = 8;
    }
    return len;
}

